#include <bits/stdc++.h>
#include "graph.h"
using namespace std;

const int N = 205;
int n, cur[N], d[N], e[N][N], id[N][N], fa[N], dis[N][N], ans[N], vis[N][N], tot[N];
vector<int> t[N], up[N], down[N]; 

int newNode(int last = 0) {
   n++; d[n] = NumberOfRoads(); fa[n] = last;
   return n;
}

void addEdge(int x, int y, int idx, int idy) {
   e[x][idx] = y, e[y][idy] = x;
   id[x][y] = idx, id[y][x] = idy;
}

void Inspect(int R) {
   int x = newNode(0);
   while (cur[x] < d[x]) {
      cur[x]++; while (cur[x] <= d[x] && e[x][cur[x]]) cur[x]++;
      if (cur[x] <= d[x]) {
         Move(cur[x], 3);
         int c = Color();
         if (c == 1) {
            t[x].push_back(cur[x]);
            int y = newNode(x);
            addEdge(x, y, cur[x], LastRoad());
            x = y;
         } else {
            c == 3 ? up[x].push_back(cur[x]) : down[x].push_back(cur[x]);
            if (c == 2) vis[x][cur[x]] = 1;
            Move(LastRoad(), c);
         }
      }
      tot[x] |= (!up[x].empty());
      while (cur[x] >= d[x] && fa[x]) {
         tot[fa[x]] |= tot[x];
         Move(id[x][fa[x]], 2), x = fa[x];
      }
   }
   if (!tot[x]) t[x].clear();
   while (!t[x].empty()) {
      int y = e[x][t[x].back()]; t[x].pop_back();
      Move(id[x][y], 2); x = y;
      if (!tot[x]) t[x].clear();
      if (!up[x].empty()) {
         vector<int> vec;
         for (auto i : up[x]) {
            Move(i, 1), vec.push_back(LastRoad()), Move(vec.back(), 3);
         }
         y = x; stack<int> stk; while (1) {
            int c = Color();
            if (c == 3) {
               addEdge(x, y, up[x].back(), down[y].back());
               up[x].pop_back(); down[y].pop_back();
               if (up[x].empty()) break;
               c = 2;
            } Move(id[y][fa[y]], c), y = fa[y]; stk.push(LastRoad());
         }
         if (vec.size() * 2 < stk.size()) {
            for (auto i : vec) {
               if (!vis[y][i]) continue;
               Move(i, 2); int c = Color();
               if (c == 1) break;
               Move(LastRoad(), c);
            }
         } else {
            while (!stk.empty()) Move(stk.top(), 2), stk.pop();
         }
      }
      while (t[x].empty() && fa[x]) {
         Move(id[x][fa[x]], 2), x = fa[x];
      }
   }
   for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) dis[i][j] = i == j ? 0 : id[i][j] ? 1 : 1e9;
   }
   for (int k = 1; k <= n; k++) {
      for (int i = 1; i <= n; i++) {
         for (int j = 1; j <= n; j++) {
            if (dis[i][k] != 1e9 && dis[k][j] != 1e9) {
               dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
            }
         }
      }
   }
   for (int i = 1; i <= n; i++) {
      for (int j = i + 1; j <= n; j++) {
         if (dis[i][j] >= 1 && dis[i][j] <= R) ans[dis[i][j]]++;
      }
   }
   for (int i = 1; i <= R; i++) Answer(i, ans[i]);
}
